<template>
	<view class="select_wrap" :style="{'width': size +'px'}">
		<view :class="['select_input',isClick?'select_input_select':'']" ref="select-input">
			<view class="input_info" @click="openSelect">
				<input :focus="isClick" @input="selectData" :value="inputValue" type="text" :readonly="readonly"
					:disabled="readonly" autocomplete="off" :placeholder="placeholder" class="text_tips">
			</view>
			<view class="icon_arrow" @click="clearItem">
				<view v-if="(!value&&!clearable) || (value&&!clearable) || (!value&&clearable) && !filterable"
					:class="['arrow',show?'arrow_down':'arrow_up']"></view>
				<view class="arrow-clear" v-if="value&&clearable">x</view>
			</view>
		</view>
		<view class="select_modal_con" v-if="show" @touchmove.stop.prevent="() => {}">
			<view class="select_modal" :style="{'height':scrollConsHeight+'px'}">
				<scroll-view :style="{'height':scrollConsHeight+'px'}" scroll-y="true" class="scroll-Y"
					:scroll-with-animation="animation" @scroll="scroll" :scroll-top="scrollTopWrapper+'px'">
					<view :style="{height:(!filterable || !inputValue)?warpHeight+'px':'max-content'}" >
						<view :style="{height:(!filterable || !inputValue)?topHeight+'px':0}"></view>
						<view class="select_content" ref="select_content" >
							<view class="select_content_li" :style="{'height':showItemDomHeight+'px'}"  v-for="(item,index) in showData" :key="index"
								:class="{'selected': value == item[valueType.value]}" @click="change(item,index)">
								{{item[valueType.label]}}
							</view>
							<view class="select_content_li" :style="{'height':showItemDomHeight+'px'}" v-if="!showData.length && !load">
								{{noDataText}}
							</view>
							<view class="select_content_li" v-if="showData.length && options.list && options.list.length">
								<template v-if="options.list.length < options.total && isVirtualFlag">
									加载中...
								</template> 
								<template v-if="(startKey+showItemNum+extraNum)>=options.total">
									已经到底啦～～
								</template>
							</view>
						</view>
						<view :style="{height:(!filterable || !inputValue)?bottomHeight+'px':0}"></view>
					</view>
				</scroll-view>
			</view>
			<view class="cons_arrow" :style="{'left': arrLeft +'px'}"></view>
		</view>
	</view>
</template>

<script>
	export default {
		props: {
			data: {
				type: Object,
				default: ()=>{}
			},
			valueType: {
				type: Object,
				default: {
					label: 'label',
					value: 'value'
				}
			},
			value: {
				type: String,
				default: ''
			},
			clearable: {
				type: Boolean,
				default: false
			},
			filterable: {
				type: Boolean,
				default: false
			},
			searchType: {
				type: Number,
				default: 1
			},
			placeholder: {
				type: String,
				default: '请选择'
			},
			noDataText: {
				type: String,
				default: '暂无数据'
			},
			arrLeft: {
				type: Number,
				default: 20
			},
			size: {
				type: Number,
				default: 240
			},
			scrollConsHeight: {
				type: Number,
				default: 170
			},
			animation: {
				type: Boolean,
				default: true
			},
			showItemDomHeight:{
				type: Number,
				default: 34
			},
			load:{
				type:Boolean,
				default:false
			},
			extraNum:{
				type: Number,
				default: 3
			}
			
		},
		data() {
			return {
				show: false,
				readonly: true,
				isClick: false,
				totalArr: [],
				showData: [],
				searchObj: {
					page: 1,
					page_size: 10000,
				},
				isVirtualFlag: false,
				options: {
					list: [],
					total: 0
				},
				disable: false,
				scrollTopWrapper:0,
				startKey:0,
				showItemNum:0,
				selectIndex:0,
				isDataEnd:false,
				inputValue:'',
				num:0,
				isScrollView:true,
				hiddenScroll:true,
				scrollTop:0,
				currentNum:0,
				topHeight:0,
				bottomHeight:0
			}
		},
		watch: {
			'filterable': {
				immediate: true,
				deep: true,
				handler(news) {
					this.readonly = !news
				}
			},
			'data'(news) {
					this.options = news
					if(this.value){
						let indexs = this.options.list.findIndex(item=>item[this.valueType.value]==this.value)
						console.log(news,'dataList',this.value,indexs)
						
						if(indexs!=-1){
							this.inputValue = this.options.list[indexs][this.valueType.label]
							this.initScrollData()
						}else if(this.options.list.length<this.options.total){
							this.getRequest()
						}else{
							uni.showToast({
								title:'数据中没有该数据'
							})
						}
					}else{
						this.initScrollData()
					}
					
				}
		},
		computed:{
			warpHeight:function(){
				return this.showItemDomHeight * this.options.list.length
			}
		},
		created() {
			console.log('created---')
		},
		methods: {
			initScrollData(){
				if(this.options.list.length && this.value){
					let indexs = this.options.list.findIndex(item=>item[this.valueType.value]==this.value)
					if(this.isScrollView){
						if(indexs!=-1){
							this.getScrollView(indexs)
							this.isScrollView = false
						}
					}
					
				}else{
					this.getScrollData()
				}
			},
			getScrollData(){
				let value = JSON.parse(JSON.stringify(this.options.list))
				this.showItemNum = Math.ceil(this.scrollConsHeight / this.showItemDomHeight)
				let chaNum = this.showItemNum + this.startKey+this.extraNum
				this.isVirtualFlag = (this.options.total>this.showItemNum+this.extraNum) && chaNum<= this.options.total ?true:false
				let datas = []
				console.log(this.startKey,chaNum,this.isVirtualFlag ,'getScrollData')
				datas = this.isVirtualFlag ? [...value.slice(this.startKey, chaNum)] : value
				this.showData = datas
			},
			openSelect() {
				this.show = !this.show
				this.isClick = !this.isClick
				
			},
			change(item,index) {
				let indexs = this.options.list.findIndex(ite=>ite[this.valueType.value]==item[this.valueType.value])
				this.getScrollView(indexs)
				this.inputValue = item[this.valueType.label]
				if (this.value != item[this.valueType.value]) {
					this.$emit('input', item[this.valueType.value])
					this.$emit('change', item[this.valueType.value])
				}
				this.show = false
				this.isClick = false
			},
			clearItem() {
				if (this.clearable) {
					this.$emit('input', '')
					this.$emit('change', '')
				}
				this.inputValue = ''
				this.getScrollView(0)
			},
			selectData(e) {
				let sel = e.detail.value
				this.inputValue = sel
				console.log(sel,'sel90909')
				if(this.options.list.length<this.options.total){
					this.getRequest()
					return
				}else{
					this.getShowData(sel)
				}
			},
			getShowData(sel){
				if (sel) {					
					let arrCons = []
					let selVal = []
					this.options.list.forEach(item => {
						arrCons.push(item)
					})
					arrCons.forEach((item,index) => {
						console.log(item, sel, 'arrCons---', item[this.valueType.label].indexOf(sel))
						if (this.searchType == 1) {
							if (item[this.valueType.label].indexOf(sel) != -1) {
								selVal.push(item)
							}
						} else {
							if (item[this.valueType.label] == sel) {
								selVal.push(item)
							}
						}
				
					})
					this.show = true
					this.$set(this,'showData',selVal)
				}else{
					this.inputValue = ''
					this.getScrollView(0)
					
				}
			},
			
			scroll(e){
				if(!this.filterable || !this.inputValue){
					let top =Math.floor( e.detail.scrollTop)
					let tempNum = Math.floor(top / this.showItemDomHeight)
					let showTotalNum = this.showItemNum+this.extraNum
					let totalNum = this.options.total
					let currentTotalNum = this.options.list.length
					console.log(top,'top=====',tempNum,this.startKey,showTotalNum+tempNum,totalNum)
					if(tempNum >0 && tempNum!=this.startKey&& showTotalNum+tempNum<=currentTotalNum && currentTotalNum<=totalNum){
						this.startKey = tempNum
						this.getScrollData()
						this.scrollTopWrapper =top
						this.topHeight = tempNum+showTotalNum<=totalNum? top:(totalNum-showTotalNum)*this.showItemDomHeight
						this.bottomHeight = this.warpHeight - (showTotalNum*this.showItemDomHeight)-this.topHeight
						return
					}
					if(tempNum==0){
						this.startKey = tempNum
						this.scrollTopWrapper =  0
						this.topHeight = top
						this.bottomHeight = (totalNum-tempNum-showTotalNum)*this.showItemDomHeight
						this.getScrollData()
						return
					}
					if(tempNum>0 && currentTotalNum<totalNum && showTotalNum+tempNum>currentTotalNum){
						this.getRequest()
					}
				}
			},
			getOptions(flag){
				this.searchObj.flag = flag
				this.$emit('httpRequest',this.searchObj)
			},
			getScrollView(index){
				this.showItemNum = Math.ceil(this.scrollConsHeight / this.showItemDomHeight)
				let showNum = this.showItemNum+this.extraNum
				if(index+showNum>=this.options.list.length && this.options.list.length<this.options.total){
					this.getRequest()
				}
				let tempNum = index+showNum<=this.options.total?index:this.options.total-showNum
				this.startKey = tempNum
				this.getScrollData()
				this.topHeight = index+showNum>this.options.total?(this.options.total-showNum)*this.showItemDomHeight: index*this.showItemDomHeight
				this.bottomHeight = this.warpHeight - (showNum*this.showItemDomHeight)-this.topHeight
				this.scrollTopWrapper = index+4>=this.options.total?(this.options.total-1)*this.showItemDomHeight: index*this.showItemDomHeight
				console.log(tempNum,'getScrollView----',this.scrollTopWrapper)
			},
			getRequest(){
				this.$emit('update:load',true)
				this.searchObj.page++
				this.getOptions(true)
			}
		},
		beforeDestroy() {}
	}
</script>

<style lang="less" scoped>
	.select_wrap {
		width: 240px;
		display: inline-block;
		position: relative;

		.select_input {
			-webkit-appearance: none;
			background-color: #fff;
			background-image: none;
			border-radius: 4px;
			border: 1px solid #dcdfe6;
			box-sizing: border-box;
			color: #606266;
			display: inline-block;
			font-size: inherit;
			height: 40px;
			line-height: 40px;
			outline: none;
			padding: 0 15px;
			box-sizing: border-box;
			transition: border-color .2s cubic-bezier(.645, .045, .355, 1);
			width: 100%;
			padding-right: 30px;
			
			.input_info {
				font-size: 12px;
				width: 100%;
				height: 100%;

				.text_tips {
					height: 100%;
				}
			}

			.icon_arrow {
				position: absolute;
				width: 30px;
				height: 40px;
				right: 0;
				top: 0;
				text-align: center;
				color: #c0c4cc;
				cursor: pointer;
				display: flex;
				justify-content: center;
				align-items: center;
				z-index: 999;

				.arrow {
					width: 10px;
					height: 10px;
					background-color: transparent;
					/* 模块背景为透明 */
					border-color: #c0c4cc;
					border-style: solid;
					border-width: 1px 1px 0 0;
					box-sizing: border-box;
					transition: all .3s;
					box-sizing: border-box;
					/*箭头方向可以自由切换角度*/
				}

				.arrow_down {
					transform: rotate(-45deg);
					margin-top: 5px;
				}

				.arrow_up {
					transform: rotate(135deg);
					margin-top: -5px;
				}

				.arrow-clear {
					width: 14px;
					height: 14px;
					border: 1px solid #e4e7ed;
					color: #e4e7ed;
					border-radius: 50%;
					display: flex;
					justify-content: center;
					align-items: center;
					font-size: 12px;
				}
			}
		}

		.select_input_select {
			border-color: #409eff;
		}
	}

	.select_modal_con {
		width: 100%;
		transform-origin: center top;
		z-index: 2062;
		position: absolute;
		top: 40px;
		left: 0;
		border: 1px solid #e4e7ed;
		border-radius: 4px;
		background-color: #fff;
		box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1);
		box-sizing: border-box;
		margin-top: 12px;

		.cons_arrow {
			position: absolute;
			display: block;
			width: 0;
			height: 0;
			border-color: transparent;
			border-style: solid;
			top: -6px;
			left: 10%;
			margin-right: 3px;
			border-top-width: 0;
			border-bottom-color: #ebeef5;

		}

		.cons_arrow:after {
			content: " ";
			border-width: 6px;
			position: absolute;
			display: block;
			width: 0;
			height: 0;
			border-color: transparent;
			border-style: solid;
			top: 1px;
			margin-left: -6px;
			border-top-width: 0;
			border-bottom-color: #fff;
		}
	}

	.select_modal {
		overflow: scroll;
		height: 160px;
		.select_content {
			list-style: none;
			margin: 0;
			box-sizing: border-box;

			.select_content_li {
				font-size: 14px;
				padding: 0 20px;
				position: relative;
				white-space: nowrap;
				overflow: hidden;
				text-overflow: ellipsis;
				color: #606266;
				height: 34px;
				line-height: 34px;
				box-sizing: border-box;
				cursor: pointer;

				&.selected {
					color: #409eff;
					font-weight: 700;
					background-color: #f5f7fa;
				}
			}

			.select_content_li:hover {
				background-color: #f5f7fa;
			}
		}



	}

	// .select_content {
	// 	background-color: #fff;

	// 	.select_content_li {
	// 		padding: 12rpx;


	// 	}
	// }
</style>
